home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Unix / skey / src / skeyinit.c < prev    next >
C/C++ Source or Header  |  1995-04-14  |  6KB  |  284 lines

  1. /* S/KEY v1.1b (skeyinit.c)
  2.  *
  3.  * Authors:
  4.  *          Neil M. Haller <nmh@thumper.bellcore.com>
  5.  *          Philip R. Karn <karn@chicago.qualcomm.com>
  6.  *          John S. Walden <jsw@thumper.bellcore.com>
  7.  *          Scott Chasin <chasin@crimelab.com>
  8.  *
  9.  * S/KEY initialization and seed update
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <pwd.h>
  15. #include <sys/resource.h>
  16. #include <time.h>
  17.  
  18. #ifdef __svr4__
  19. #include <sys/systeminfo.h>
  20. #include <unistd.h>
  21. #include <shadow.h>
  22. #include "sysv_shadow.h"
  23. #endif /* __svr4__ */
  24.  
  25. #include "skey.h"
  26.  
  27. extern int optind;
  28. extern char *optarg;
  29.  
  30. char *readpass (), *malloc (), *getpass (), *crypt ();
  31.  
  32. int skeylookup __ARGS ((struct skey * mp, char *name));
  33.  
  34. #define NAMELEN 2
  35.  
  36.  
  37. main (argc, argv)
  38.   int argc;
  39.   char *argv[];
  40. {
  41.   int rval, n, nn, i, defaultsetup, l;
  42.   time_t now;
  43.   char seed[18], tmp[80], key[8], defaultseed[17], passwd[256], passwd2[256],
  44.        tbuf[27], buf[60], lastc, me[80], user [8], *salt, *p, *pw; 
  45.   struct skey skey;
  46.   struct passwd *pp;
  47.   struct tm *tm;
  48.  
  49.  
  50.   time (&now);
  51.   tm = localtime (&now);
  52.   strftime (tbuf, sizeof (tbuf), "%M%j", tm);
  53.  
  54.   if ((gethostname (defaultseed, sizeof (defaultseed))) < 0)
  55.       exit (-1);
  56.  
  57.   strcpy (&defaultseed[NAMELEN], tbuf);
  58.  
  59.   pp = getpwuid (getuid ());
  60.   strcpy (me, pp->pw_name);
  61.  
  62.   if ((pp = getpwnam (me)) == NULL) {
  63.      fprintf(stderr, "Who are you?\n");
  64.      exit(1);
  65.   }
  66.  
  67.   defaultsetup = 1;
  68.  
  69.   if (argc > 1)
  70.   {
  71.     if (strcmp ("-s", argv[1]) == 0)
  72.       defaultsetup = 0;
  73.     else
  74.       pp = getpwnam (argv[1]);
  75.  
  76.     if (argc > 2)
  77.       pp = getpwnam (argv[2]);
  78.  
  79.   }
  80.  
  81.   if (pp == NULL)
  82.   {
  83.     printf ("User unknown\n");
  84.     exit (1);
  85.   }
  86.  
  87.   if (strcmp (pp->pw_name, me) != 0)
  88.   {
  89.     if (getuid () != 0)
  90.     {
  91.       /* Only root can change other's passwds */
  92.       printf ("Permission denied.\n");
  93.       exit (1);
  94.     }
  95.   }
  96.  
  97.   salt = pp->pw_passwd;
  98.  
  99.   setpriority (PRIO_PROCESS, 0, -4);
  100.  
  101.   if (getuid () != 0) {
  102.      setpriority (PRIO_PROCESS, 0, -4);
  103.  
  104.      pw = getpass ("Password:");
  105.      p = crypt (pw, salt);
  106.  
  107.      setpriority(PRIO_PROCESS, 0, 0);
  108.  
  109.      if (pp && strcmp(p, pp->pw_passwd)) {
  110.         printf ("Password incorrect.\n");
  111.         exit (-1);
  112.      }
  113.   }
  114.  
  115.   rval = skeylookup (&skey, pp->pw_name);
  116.   switch (rval)
  117.   {
  118.   case -1:
  119.     perror ("Error opening database: ");
  120.     exit (1);
  121.   case 0:
  122.     printf ("[Updating %s]\n", pp->pw_name);
  123.     printf ("Old key: %s\n", skey.seed);
  124.  
  125.     /* lets be nice if they have a skey.seed that ends in 0-8 just add one */
  126.     l = strlen (skey.seed);
  127.     if (l > 0)
  128.     {
  129.       lastc = skey.seed[l - 1];
  130.       if (isdigit (lastc) && lastc != '9')
  131.       {
  132.     strcpy (defaultseed, skey.seed);
  133.     defaultseed[l - 1] = lastc + 1;
  134.       }
  135.       if (isdigit (lastc) && lastc == '9' && l < 16)
  136.       {
  137.     strcpy (defaultseed, skey.seed);
  138.     defaultseed[l - 1] = '0';
  139.     defaultseed[l] = '0';
  140.     defaultseed[l + 1] = '\0';
  141.       }
  142.     }
  143.     break;
  144.   case 1:
  145.     printf ("[Adding %s]\n", pp->pw_name);
  146.     break;
  147.   }
  148.   n = 99;
  149.  
  150.   if (!defaultsetup)
  151.   {
  152.     printf ("You need the 6 english words generated from the \"key\" command.\n");
  153.     for (i = 0 ;; i++)
  154.     {
  155.       if (i >= 2)
  156.     exit (1);
  157.       printf ("Enter sequence count from 1 to 10000: ");
  158.       fgets (tmp, sizeof (tmp), stdin);
  159.       n = atoi (tmp);
  160.       if (n > 0 && n < 10000)
  161.     break;        /* Valid range */
  162.       printf ("\n Error: Count must be > 0 and < 10000\n");
  163.     }
  164.   }
  165.  
  166.   if (!defaultsetup)
  167.   {
  168.     printf ("Enter new key [default %s]: ", defaultseed);
  169.     fflush (stdout);
  170.     fgets (seed, sizeof (seed), stdin);
  171.     rip (seed);
  172.     if (strlen (seed) > 16)
  173.     {
  174.       printf ("Notice: Seed truncated to 16 characters.\n");
  175.       seed[16] = '\0';
  176.     }
  177.  
  178.     if (seed[0] == '\0')
  179.       strcpy (seed, defaultseed);
  180.  
  181.     for (i = 0 ;; i++)
  182.     {
  183.       if (i >= 2)
  184.     exit (1);
  185.  
  186.       printf ("s/key %d %s\ns/key access password: ", n, seed);
  187.       fgets (tmp, sizeof (tmp), stdin);
  188.       rip (tmp);
  189.       backspace (tmp);
  190.  
  191.       if (tmp[0] == '?')
  192.       {
  193.     printf ("Enter 6 English words from secure S/Key calculation.\n");
  194.     continue;
  195.       }
  196.  
  197.       if (tmp[0] == '\0')
  198.       {
  199.     exit (1);
  200.       }
  201.       if (etob (key, tmp) == 1 || atob8 (key, tmp) == 0)
  202.     break;            /* Valid format */
  203.       printf ("Invalid format - try again with 6 English words.\n");
  204.     }
  205.   }
  206.   else
  207.   {
  208.     /* Get user's secret password */
  209.     for (i = 0 ;; i++)
  210.     {
  211.  
  212.       if (i >= 2)
  213.     exit (1);
  214.  
  215.       printf ("Enter secret password: ");
  216.       readpass (passwd, sizeof (passwd));
  217.  
  218.       if (passwd[0] == '\0')
  219.     exit (1);
  220.  
  221.       printf ("Again secret password: ");
  222.       readpass (passwd2, sizeof (passwd));
  223.  
  224.       if (passwd2[0] == '\0')
  225.     exit (1);
  226.  
  227.       if (strlen (passwd) < 4 && strlen (passwd2) < 4)
  228.       {
  229.     fprintf (stderr, "Error: Your password must be longer.\n\r");
  230.     exit (1);
  231.       }
  232.  
  233.       if (strcmp (passwd, passwd2) == 0)
  234.     break;
  235.  
  236.       printf ("Error: Passwords dont match.\n");
  237.     }
  238.     strcpy (seed, defaultseed);
  239.  
  240.     /* Crunch seed and password into starting key */
  241.     if (keycrunch (key, seed, passwd) != 0)
  242.     {
  243.       fprintf (stderr, "%s: key crunch failed.\n", argv[0]);
  244.       exit (2);
  245.     }
  246.     nn = n;
  247.     while (nn-- != 0)
  248.       f (key);
  249.   }
  250.   time (&now);
  251.   tm = localtime (&now);
  252.   strftime (tbuf, sizeof (tbuf), " %b %d,%Y %T", tm);
  253.  
  254.   skey.val = malloc (16 + 1);
  255.  
  256.   btoa8 (skey.val, key);
  257.  
  258.   fprintf (skey.keyfile, "%s %04d %-16s %s %-21s\n", pp->pw_name, n,
  259.        seed, skey.val, tbuf);
  260.   fclose (skey.keyfile);
  261.   printf ("\nID %s s/key is %d %s\n", pp->pw_name, n, seed);
  262.   printf ("Next login password: %s\n", btoe (buf, key));
  263. #ifdef HEXIN
  264.   printf ("%s\n", put8 (buf, key));
  265. #endif
  266.  
  267.   exit (1);
  268. }
  269.  
  270. #ifdef __svr4__
  271. int gethostname (name, len)
  272. char *name;
  273. int len;
  274.    int  namelen = 128;
  275.  
  276.    if (sysinfo (SI_HOSTNAME, name, len) <0)  {
  277.         perror("hostname");
  278.         return -1;
  279.    }
  280.    return 0;
  281. }
  282. #endif
  283.